"""
NetworkMakerPlayer.py

Author: Zach Epolito
Date: 10-04-08

$Id: NetworkMakerPlayer.py 336 2008-10-17 03:45:49Z arguas2617 $
"""

from NetworkWaitFrame import NetworkWaitFrame
from Game import Game
from threading import Thread
from UndoCommand import UndoCommand
from MoveCommand import MoveCommand
from MakerMove import MakerMove
from WaitFrame import WaitFrame
import socket

"""represents a player on the network making a move"""
class NetworkMakerPlayer(Thread):

    """Constructor."""
    def __init__(self, game, host, gui, waitTime):
        Thread.__init__(self)
        
        self.game = game
        self.host = host
        self.gui = gui
        self.waitTime = waitTime
                
        game.register_observer(self)

        self.start()

    """Runs a thread waiting for input from
       the network breaker player"""
    def run(self):

        if self.host == "":
            #server
            #try:
            server_sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
            server_sock.bind(('0.0.0.0', 1527))
            server_sock.listen(1)
            self.conn, info = server_sock.accept()
            
            #except e:
                #print e
        else:
            #client
            #try:
            client_sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
            client_sock.connect((self.host, 1518))
            self.conn = client_sock
            #except e:
                #print e
          
        msg = None
        while 1:
            msg = self.conn.recv(1024)
            if (msg != None):
                self.handleSocket(msg)
                msg = None

    """Deciphers the string returned by the coket
       and handles related command"""
    def handleSocket(self, msg):
        #Display waiting in GUI
        frame = NetworkWaitFrame(self.gui.getRootInputView(), width=300, height=100)
        self.gui.set_input_view(frame)

        #Starts a new thread and waits for
        #the network player to make a move.
        """To be implemented"""
        splitter = msg.split(' ')
        #Determines what type of move the
        #network player made

        #A breaker move is ignored.
        if (splitter[0] == 'g'):
            self.startFunctor()
        
        #A maker move
        if (splitter[0] == 'f'):
            guess = [None,None,None,None]
            move = [None,None,None,None,None]
            move = splitter

            #loops index from 1-4
            for index in range(1, 5):
                if (move[index] == 'x'):
                    guess[index-1] = 0
                if (move[index] == 'w'):
                    guess[index-1] = 1
                if (move[index] == 'b'):
                    guess[index-1] = 2

            self.makerMove = MakerMove(guess)

            if self.game.turn == self.game.MAKER_TURN :
                self.moveCommand.execute(self.makerMove)

        #Undo
        if (msg[0] == 'u'):
            self.undoCommand.execute()

        #A winner has been declared
        if (msg[0] == 'w'):
            self.winCommand.execute()

        #New game
        if (msg[0] == 'n'):
            self.newGameCommand.execute()

        #Exit game
        if (msg[0] == 'e'):
            self.closeCommand.execute()

    """Passes messages through the socket to the
       network player"""
    #Currently only passing moves and undo's are implemented
    def update(self, subject, param):
        
        if subject == self.game: 
            if param == self.game.NOTIFY_MOVE:
                if self.game.turn == self.game.MAKER_TURN : 
                    frame = NetworkWaitFrame(self.gui.getRootInputView(),
                                                      width=300, height=100)
                    self.gui.set_input_view(frame)
                    self.sendCommand(self.game.get_last_move().get_network_string())
            elif param == Game.NOTIFY_UNDO:
                self.sendCommand('u')

    def sendCommand(self, msg):
        self.conn.send(msg)
        
    def setStartingCode(self, startFunctor):
        self.startFunctor = startFunctor
        frame = NetworkWaitFrame(self.gui.getRootInputView(),
                                     width=300, height=100)
        self.gui.set_input_view(frame)
        

    def setWaitTime(self, waitTime):
        self.waitTime = waitTime

    def setCommands(self, undoCommand, winCommand, moveCommand,
                    exitCommand, newGameCommand):
        self.moveCommand = moveCommand
        self.undoCommand = undoCommand
        self.winCommand = winCommand
        self.exitCommand = exitCommand
        self.newGameCommand = newGameCommand

    """handle if new game or exit command is executed"""
    def handleCommandExecuted(self, cmd):
        if cmd == 'exit':
            self.sendCommand('e')
        elif cmd == 'new':
            self.sendCommand('n')
